#include "tacheTraitementCommandes.h"
 
int TraitementCommandes(MSG_Q_ID _idBalLogs, MSG_Q_ID _idBalIHM, MSG_Q_ID _idBalLots, MSG_Q_ID _idBalCommandes, MSG_Q_ID _idBalErreurs, int _idMiseEnCarton, int _idMiseEnPalette, int _idStockage)
{
	moteur_TraitementCommandes( _idBalLogs,  _idBalIHM,  _idBalLots,  _idBalCommandes,  _idBalErreurs,  _idMiseEnCarton,  _idMiseEnPalette,  _idStockage);
}

void moteur_TraitementCommandes(MSG_Q_ID idBalLogs, MSG_Q_ID idBalIHM, MSG_Q_ID idBalLots, MSG_Q_ID idBalCommandes, 
		MSG_Q_ID idBalErreurs, int idMiseEnCarton, int idMiseEnPalette, int idStockage)
{
	MESSAGE_LOT messageLot;
	MESSAGE_LOG_ERR log;
	MESSAGE_IHM messageIHM;
	TYPEPIECE typeLot;
	MESSAGE_IHM ordre;
	

	
	int *secondes, *minutes, *heures, *jour, *mois, *annee, nbPiecesA, nbPiecesB;
	int numLot =0;
	
	
	for(;;)
	{
		if( msgQReceive(idBalCommandes, (char *) &ordre, sizeof(MESSAGE_IHM),WAIT_FOREVER) != ERROR)
		{
			switch(ordre.typeObjet)
			{
			//Traitement sur le système global
			case 0:
				if(strcmp(ordre.message,"arret") == 0)
				{
				//Arret et propagation du message
					messageLot.codeOperateur = NULL;
					messageLot.nombrePalettes = NULL;
					messageLot.numeroLot = ordre.idObjet;
					messageLot.typePieces = NULL;
					msgQSend(idBalLots,(char *) &messageLot, sizeof(MESSAGE_LOT), WAIT_FOREVER,MSG_PRI_NORMAL);
					return;
				}else{
					if(strcmp(ordre.message,"reprendre") == 0)
					{
						taskResume(idStockage);
						taskResume(idMiseEnPalette);
						taskResume(idMiseEnCarton);
						strcpy(log.message , "reprise avec conservation du lot");
						strcpy(messageIHM.message , "reprise");
						messageIHM.idObjet = ordre.idObjet;
						messageIHM.type = MESSIHM_INFORMATION;
						messageIHM.typeObjet = 8;
					}else if(strcmp(ordre.message,"supprimer") == 0){
							retirerPalettesStockees(ordre.idObjet);
							taskRestart(idStockage);
							taskRestart(idMiseEnPalette);
							taskRestart(idMiseEnCarton);
							strcpy(log.message , "reprise sans conservation du lot");
							strcpy(messageIHM.message , "interruption");
							messageIHM.idObjet = ordre.idObjet;
							messageIHM.type = MESSIHM_REPONSE;
							messageIHM.typeObjet = 8;
						}else if(strcmp(ordre.message,"arreturgent") == 0){
							messageIHM.idObjet = -1;
							messageIHM.type = MESSIHM_REPONSE;
							messageIHM.typeObjet = 0;
							strcpy(messageIHM.message , "arreturgent");
							strcpy(log.message , "bouton arret urgent traite");
						}
				}
				break;
			//Traitement imprimante
			case 1:
				etatImprimante = 0;
				log.type = LOG_NORMAL;
				log.type_erreur = NULL;
				strcpy(log.message, "Imprimante reparee");
				strcpy(messageIHM.message, "repare");
				messageIHM.idObjet = -1;
				messageIHM.type = MESSIHM_REPONSE;
				messageIHM.typeObjet = 1;
				break;
			case 2:
			//Traitement arrivée pièce
				log.type = LOG_NORMAL;
				log.type_erreur = NULL;
				strcpy(log.message, "Arrivee piece reparee");
				strcpy(messageIHM.message, "repare");
				messageIHM.idObjet = -1;
				messageIHM.type = MESSIHM_REPONSE;
				messageIHM.typeObjet = 2;
				break;
			case 3:
			//Traitement absence carton
				capteurCarton =0;
				messageIHM.idObjet = -1;
				messageIHM.type = MESSIHM_REPONSE;
				messageIHM.typeObjet = 3;
				strcpy(messageIHM.message , "repare");
				strcpy(log.message , "absence carton reparee");
				break;
			case 4:
			//Tratiement blocage file d'attente
				messageIHM.idObjet = -1;
				messageIHM.type = MESSIHM_REPONSE;
				messageIHM.typeObjet = 4;
				strcpy(messageIHM.message , "repare");
				strcpy(log.message , "atelier mise en palette debloque");
				break;
			case 5:
			//Traitement absence palette
				capteurPalette =0;
				log.type = LOG_NORMAL;
				log.type_erreur = NULL;
				strcpy(log.message, "Absence palette corrigee");
				strcpy(messageIHM.message, "repare");
				messageIHM.idObjet = -1;
				messageIHM.type = MESSIHM_REPONSE;
				messageIHM.typeObjet = 5;
			case 6:
				//Régler taux de pieces défectueuses dans la simulation
				strcpy(log.message, "Taux de pieces defectueuse corrige");
				strcpy(messageIHM.message, "repare");
				messageIHM.idObjet = -1;
				messageIHM.type = MESSIHM_REPONSE;
				messageIHM.typeObjet = 6;
				break;
			case 8:
			//Traitement d'un lot
				messageLot.piecesDefectueusesMax= atoi(substring((char *)(ordre.message),4,' '));
				messageLot.codeOperateur = atoi(substring((char *)(ordre.message),3,' '));
				messageLot.nombrePalettes = atoi(substring((char *)(ordre.message),2,' '));
				messageLot.numeroLot = ordre.idObjet;
				messageLot.typePieces = atoi(substring((char *)(ordre.message),1,' '));
				msgQSend(idBalLots,(char *) &messageLot, sizeof(MESSAGE_LOT), WAIT_FOREVER,MSG_PRI_NORMAL);
				if(ordre.idObjet == -1)
					return;
				break;
			case 9:
			//Traitement d'une commande d'expédition
				nbPiecesA = atoi(substring((char *)ordre.message,1,' '));
				nbPiecesB = atoi(substring((char *)ordre.message,2,' '));
				if(verifierCommande(nbPiecesA,nbPiecesB) ==1)
				{
					//La command est prête
					traiterCommande(nbPiecesA,nbPiecesB);
					sprintf(log.message, "Commande expédiée: nbPièces A: %d, nbPiècesB: %d", nbPiecesA,nbPiecesB);
					strcpy(log.message, "Commande satisfaite");
					strcpy(messageIHM.message, "envoye");
					messageIHM.idObjet = ordre.idObjet;
					messageIHM.type = MESSIHM_REPONSE;
					messageIHM.typeObjet = 9;
					
				}else{
					//La commande n'est pas prête
					strcpy(log.message, "commande non prete");
					log.type = MESS_ERREUR;
					log.type_erreur = ERR_COMMANDE_NON_PRETE;
					getDateCourante(secondes,minutes,heures,jour,mois,annee);
					log.sec = *secondes;
					log.min = * minutes;
					log.h = *heures;
					log.jour = *jour;
					log.mois = *mois;
					log.annee = *annee;
					msgQSend(idBalErreurs, (char *)&log,sizeof(MESSAGE_LOG_ERR), WAIT_FOREVER,MSG_PRI_NORMAL);
				}
				break;
			case 10:
			//Traitement film plastique
				capteurFilmPlastique =0;
				log.type = LOG_NORMAL;
				log.type_erreur = NULL;
				strcpy(log.message, "Machine plastifeuse depannee");
				strcpy(messageIHM.message, "repare");
				
				messageIHM.idObjet = 6;
				messageIHM.type = MESSIHM_INFORMATION;
				messageIHM.typeObjet = -1;
				break;
			default: break;
			}
			
		}
		//Informations communes à tous les traitements, sauf en cas d'arret, traitement commabde expédition ou traitement d'un lot
		if((strcmp(ordre.message,"arret")!=0) && (ordre.typeObjet !=8) && (log.type != LOG_ERREUR) && (ordre.typeObjet !=9)){
			getDateCourante(secondes,minutes,heures,jour,mois,annee);
			log.type = LOG_NORMAL;
			log.type_erreur = NULL;
			log.sec = *secondes;
			log.min = * minutes;
			log.h = *heures;
			log.jour = *jour;
			log.mois = *mois;
			log.annee = *annee;
			messageIHM.heures = *heures;
			messageIHM.minutes = *minutes;
			messageIHM.secondes = *secondes;
			msgQSend(idBalLogs,(char *) &log, sizeof(MESSAGE_LOG_ERR), WAIT_FOREVER,MSG_PRI_NORMAL);
			msgQSend(idBalIHM , (char *) &messageIHM,sizeof(MESSAGE_IHM), WAIT_FOREVER,MSG_PRI_NORMAL);
		}
	}
	
}

int verifierCommande(int nbPalettesA, int nbPalettesB)
{
	if((nbPalettesA <= countPalettesA()) && (nbPalettesB <= countPalettesB()))
		return 1;
	else
		return 0;
}

int countPalettesA()
{
	int i =0;
	int nbPalettes=0;
	for(i=0; i<MAX_PALETTES; i++)
	{
		if(paletteTypeA[i] != NULL)
		{
			nbPalettes++;
		}
	}
	return nbPalettes;
}

int countPalettesB()
{
	int i =0;
	int nbPalettes=0;
	for(i=0; i<MAX_PALETTES; i++)
	{
		if(paletteTypeB[i] != NULL)
		{
			nbPalettes++;
		}
	}
	return nbPalettes;
}
void traiterCommande(int nbPalettesA, int nbPalettesB)
{
	int i =0;
	for(i=0; nbPalettesA > 0; i++)
	{
		if(paletteTypeA[i] != NULL)
		{
			paletteTypeA[i] = NULL;
			nbPalettesA--;
		}
	}
	
	for(i=0; nbPalettesA > 0; i++)
	{
		if(paletteTypeB[i] != NULL)
		{
			paletteTypeB[i] = NULL;
			nbPalettesB--;
		}
	}
}

void retirerPalettesStockees(int _numLot)
{
	int i=0;
	for(i=0; i < MAX_PALETTES; i++)
	{
		if(paletteTypeA[i]->numLot == _numLot)
		{
			paletteTypeA[i] = NULL;
		}
	}
	
	for(i=0; i < MAX_PALETTES; i++)
	{
		if(paletteTypeB[i]->numLot == _numLot)
		{
			paletteTypeB[i] = NULL;
		}
	}
}
